/*
 * GPIO5.c
 *
 *  Created on: Mar 22, 2021
 *      Author: xrj
 */

#include "GPIO5.h"

//integer 0-4 convert to GPIO_State5;
GPIO_State5 GPIO_S5[5] = {GPIO_Stro_down, GPIO_Week_down,
		GPIO_Float, GPIO_Week_up, GPIO_Stro_up};

/*
 * @brief init GPIO to float state
 * @param GPIOx     : x=A..G
 * @param GPIO_PinN : integer 0-15
 */
void GPIO_Init5(GPIO_TypeDef* GPIOx, uint32_t PinX)
{
	GPIO_Set5(GPIOx, PinX, GPIO_Float);
}

/*
 * @brief set GPIO Pin state
 * @param GPIOx     : x=A..G
 * @param GPIO_PinN : integer 0-15
 * @param NewState  : new state will write to Pin
 */
void GPIO_Set5(GPIO_TypeDef* GPIOx, uint32_t PinX, GPIO_State5 NewState)
{
	uint32_t bsrr = 1 << (PinX + ~(NewState|IsUp_IMsk));  // bit and result is 0 or 16
	uint32_t crlh = NewState & CRLH_Msk;
	__IO uint32_t *CRx = (PinX < 8) ? &GPIOx->CRL : &GPIOx->CRH;
	uint32_t offset = (PinX < 8) ? (PinX<<2U) : ((PinX-8u) << 2U);
    if(NewState & Stro_Msk){
        GPIOx->BSRR = bsrr;
        MODIFY_REG(*CRx, CRLH_Msk<<offset, crlh<<offset);
    }else{
    	MODIFY_REG(*CRx, CRLH_Msk<<offset, crlh<<offset);
        GPIOx->BSRR = bsrr;
    }
}

/*
 * @brief  set CRL/CRH register for Pin.
 *         only for STM32F1.
 * @param GPIOx : x=A..G
 * @param PinX  : integer 0-15
 * @param crlh  : 4bit value
 *                 b3  |  b2  |   b1  |  b0
 *                CNF1 | CNF0 | MODE1 | MODE0
 */
void GPIO_SetCRLH(GPIO_TypeDef* GPIOx, uint32_t PinX, uint32_t crlh)
{
	crlh &= CRLH_Msk;
	uint32_t offset = (PinX < 8) ? (PinX<<2U) : ((PinX-8u) << 2U);
    __IO uint32_t *CRx = (PinX < 8) ? &GPIOx->CRL : &GPIOx->CRH;
    uint32_t  CRx_new = (*CRx & (~(CRLH_Msk<<offset))) | crlh<<offset;
    *CRx = CRx_new;
}
